During the life cycle of a software application, there is often a need to observe how the application is behaving as it executes under typical running conditions. During the development phase, program behavior can be observed using a debugger. It is not always practical to use a debugger, however, as stopping a program at a break point can change the behavior of a program, especially in multi-threaded programs. Thus, placing traces in a program can sometimes be the only option.
Inserting debugging or tracing code in the source code of a program or application can have certain drawbacks. If debugging code is inserted in several places throughout an application, the source code can become cluttered with debug logic. Also, a programmer will have to anticipate the correct places to put the debug code when inserting it into the application. Once compiled, such debugging code cannot be changed. This can be undesirable while dealing with publicly-released software.
If a problem is reported against a specific release of a product, for example, the customer support staff may have to perform several tasks to put the required diagnostic code into the application. First, it is necessary to get an exact copy of the source code from which the released product was built. Then, diagnostic logic must be manually inserted at appropriate places in the source code. The application then needs to be built in exactly the same manner in which the released product was built. If the added diagnostic code needs any further tuning, it may need to be changed by hand and the whole application rebuilt. This process can be very tedious and time consuming.
If the problem is in a third party library or module, the source code may not be available at all. In this case, altering the source code to add diagnostic logic is simply not possible.